package net.huashitong.ssydt.provider.exam.api;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import net.huashitong.ssydt.exam.entity.vo.*;
import net.huashitong.ssydt.provider.annotations.LoginRequired;
import net.huashitong.ssydt.provider.exam.service.ExamService;
import net.huashitong.ssydt.provider.utils.StringUtils;
import net.huashitong.ssydt.provider.web.model.Result;
import net.huashitong.ssydt.provider.web.utils.ResultUtils;
import net.huashitong.ssydt.security.utils.UserUtils;
import net.huashitong.ssydt.sys.entity.SsSysBas;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;

/**
 * @author <a href="mailto:yhy23456@163.com">huiyang.yu</a>
 * @since 2017.08.14
 */
@Api(value = "/api/exam/", tags = {"测评模块"})
@RestController
@RequestMapping("/api/exam/")
public class ApiExamController {

    private ExamService examService;

    @Autowired
    public ApiExamController(ExamService examService) {
        this.examService = examService;
    }

    @ApiOperation(value = "获取我的考试信息", notes = "获取我的考试信息", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @GetMapping("/infos/my")
    public Result<ExamInfoVO> getInfosMy() {
        String userId = UserUtils.getUserId();
        ExamInfoVO examInfoVO = examService.getInfosMy(userId);
        return ResultUtils.getSuccessResults(examInfoVO);
    }


    @ApiOperation(value = "修改我的考试信息", notes = "修改我的考试信息", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @PutMapping("/infos/my")
    public Result<String> putInfosMy(@Valid @RequestBody ExamInfoVO examInfoVO) {
        String userId = UserUtils.getUserId();
        examService.putInfosMy(userId, examInfoVO);
        return ResultUtils.getSuccessResults();
    }

    @ApiOperation(value = "获取我的刷题进度", notes = "获取我的刷题进度", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @GetMapping("/tests/my")
    public Result<TestsOutVo> getTestsMy() {
        String userId = UserUtils.getUserId();
        TestsOutVo testsOutVo = examService.getTestsMy(userId);
        return ResultUtils.getSuccessResults(testsOutVo);
    }


    @ApiOperation(value = "制定（重置）刷题计划", notes = "制定（重置）刷题计划", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @PostMapping("/tests")
    public Result<String> postTests() {
        String userId = UserUtils.getUserId();
        examService.postTests(userId);
        return ResultUtils.getSuccessResults();
    }

    @ApiOperation(value = "开始（继续）全真刷题", notes = "开始（继续）全真刷题", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @PostMapping("/test/records")
    public Result<TestRecordVo> postTestRecords() {
        String userId = UserUtils.getUserId();
        TestRecordVo testRecordsVo = examService.postTestRecords(userId);
        return ResultUtils.getSuccessResults(testRecordsVo);
    }

    @ApiOperation(value = "同步全真刷题进度", notes = "同步全真刷题进度", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @PutMapping("/test/records/{recordId}")
    public Result<String> putTestRecordsById(
            @ApiParam(value = "记录id", required = true) @PathVariable("recordId") Long recordId,
            @Valid @RequestBody TestRecordsByIdInVo testRecordsByIdInVo) {
        examService.putTestRecordsById(recordId, testRecordsByIdInVo);
        return ResultUtils.getSuccessResults();
    }

    @ApiOperation(value = "全真刷题交卷", notes = "全真刷题交卷", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @PostMapping("/test/records/{recordId}")
    public Result<String> postTestRecordsById(
            @ApiParam(value = "记录id", required = true) @PathVariable("recordId") Long recordId,
            @Valid @RequestBody TestRecordsByIdInVo testRecordsByIdInVo) {
        examService.postTestRecordsById(recordId, testRecordsByIdInVo);
        return ResultUtils.getSuccessResults();
    }

    @ApiOperation(value = "查看全真刷题测评报告", notes = "查看全真刷题测评报告", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @GetMapping("/test/records/{recordId}")
    public Result<TestRecordVo> getTestRecordsById(
            @ApiParam(value = "记录id", required = true) @PathVariable("recordId") Long recordId) {
        TestRecordVo testRecordVo = examService.getTestRecordsById(recordId);
        return ResultUtils.getSuccessResults(testRecordVo);
    }

    @ApiOperation(value = "获取我的刷题记录列表", notes = "获取我的刷题记录列表", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @GetMapping("/test/records/my")
    public Result<ArrayList<TestRecordsListOutVO>> getTestRecordsListMy(@ModelAttribute TestRecordsListInVO testRecordsListInVO) {
        String userId = UserUtils.getUserId();
        testRecordsListInVO.setUserId(userId);
        List<TestRecordsListOutVO> testRecordsListOutVOs = examService.getTestRecordsListMy(testRecordsListInVO);
        return ResultUtils.getSuccessResultList(testRecordsListOutVOs);
    }

    @ApiOperation(value = "清除（停用）全真刷题计划", notes = "清除（停用）全真刷题计划", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @DeleteMapping("/tests")
    public Result<String> deleteTests() {
        String userId = UserUtils.getUserId();
        examService.deleteTests(userId);
        return ResultUtils.getSuccessResults();
    }

    @ApiOperation(value = "试卷列表", notes = "试卷列表", produces = MediaType.APPLICATION_JSON_VALUE)
    @GetMapping("/papers")
    public Result<ArrayList<PaperListOutVO>> getPapers(@Valid @ModelAttribute PaperListInVO paperListInVO) {
        String userId = UserUtils.getUserId();
        List<PaperListOutVO> paperListOutVOS = examService.getPapers(userId, paperListInVO);
        return ResultUtils.getSuccessResultList(paperListOutVOS);
    }

    @ApiOperation(value = "试卷（题库）作答", notes = "试卷（题库）作答", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @PostMapping("/paper/{paperId}/records")
    public Result<PaperRecordOutVO> postPaperRecords(
            @ApiParam(value = "试卷id", required = true) @PathVariable("paperId") Long paperId) {
        String userId = UserUtils.getUserId();
        PaperRecordOutVO paperRecordOutVO = examService.postPaperRecords(userId, paperId);
        return ResultUtils.getSuccessResults(paperRecordOutVO);
    }

    @ApiOperation(value = "同步试卷（题库）进度", notes = "同步试卷（题库）进度", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @PutMapping("/paper/records/{recordId}")
    public Result<String> putRecords(
            @ApiParam(value = "试卷记录id", required = true) @PathVariable("recordId") Long recordId,
            @Valid @RequestBody PaperRecordInVO paperRecordInVO) {
        examService.putRecords(recordId, paperRecordInVO);
        return ResultUtils.getSuccessResults();
    }

    @ApiOperation(value = "试卷（题库）交卷", notes = "试卷（题库）交卷", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @PostMapping("/paper/records/{recordId}")
    public Result<String> postRecords(
            @ApiParam(value = "试卷记录id", required = true) @PathVariable("recordId") Long recordId,
            @Valid @RequestBody PaperRecordInVO paperRecordInVO) {
        examService.postRecords(recordId, paperRecordInVO);
        return ResultUtils.getSuccessResults();
    }

    @ApiOperation(value = "获取试卷（题库）作答报告", notes = "获取试卷（题库）作答报告", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @GetMapping("/paper/records/{recordId}")
    public Result<PaperRecordOutVO> getRecords(
            @ApiParam(value = "试卷记录id", required = true) @PathVariable("recordId") Long recordId) {
        PaperRecordOutVO paperRecordOutVO = examService.getRecords(recordId);
        return ResultUtils.getSuccessResults(paperRecordOutVO);
    }


    @ApiOperation(value = "我的错题列表", notes = "我的错题列表", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @GetMapping("/errors")
    public Result<ArrayList<QuestionErrorListOutVO>> getErrors(
            @Valid @ModelAttribute QuestionErrorCollectionListInVO questionErrorCollectionListInVO) {
        String userId = UserUtils.getUserId();
        questionErrorCollectionListInVO.setUserId(userId);
        String lastBelongYearMonth = executeBelongYearMonthURLDecoder(questionErrorCollectionListInVO.getLastBelongYearMonth());
        questionErrorCollectionListInVO.setLastBelongYearMonth(lastBelongYearMonth);
        List<QuestionErrorListOutVO> questionErrorListOutVOS = examService.getErrors(questionErrorCollectionListInVO);
        return ResultUtils.getSuccessResultList(questionErrorListOutVOS);
    }


    @ApiOperation(value = "获取错题内容列表", notes = "获取错题内容列表", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @GetMapping("/error/{belongYearMonth}/questions")
    public Result<QuestionErrorVO> getErrorQuestions(
            @ApiParam(value = "所属年月", required = true)
            @PathVariable("belongYearMonth") String belongYearMonth) {
        String userId = UserUtils.getUserId();
        belongYearMonth = executeBelongYearMonthURLDecoder(belongYearMonth);
        QuestionErrorVO questionErrorVO = examService.getErrorQuestions(userId, belongYearMonth);
        return ResultUtils.getSuccessResults(questionErrorVO);
    }

    @ApiOperation(value = "同步错题进度", notes = "同步错题进度", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @PutMapping("/error/records/{belongYearMonth}")
    public Result<String> putErrorRecords(
            @ApiParam(value = "所属年月", required = true) @PathVariable("belongYearMonth") String belongYearMonth,
            @Valid @RequestBody ErrorRecordsInVO errorRecordsInVO) {
        String userId = UserUtils.getUserId();
        belongYearMonth = executeBelongYearMonthURLDecoder(belongYearMonth);
        errorRecordsInVO.setUserId(userId);
        examService.putErrorRecords(belongYearMonth, errorRecordsInVO);
        return ResultUtils.getSuccessResults();
    }


    @ApiOperation(value = "移除错题", notes = "移除错题", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @DeleteMapping("/error/questions/{errorQuestionId}")
    public Result<String> deleteErrorQuestion(
            @ApiParam(value = "错题表Id", required = true) @PathVariable("errorQuestionId") Long errorQuestionId) {
        examService.deleteErrorQuestion(errorQuestionId);
        return ResultUtils.getSuccessResults();
    }


    @ApiOperation(value = "清空错题", notes = "清空错题", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @DeleteMapping("/error/questions")
    public Result<String> deleteErrorQuestions() {
        String userId = UserUtils.getUserId();
        examService.deleteErrorQuestions(userId);
        return ResultUtils.getSuccessResults();
    }

    @ApiOperation(value = "题库分类列表", notes = "题库分类列表", produces = MediaType.APPLICATION_JSON_VALUE)
    @GetMapping("/paper/parameter/types")
    public Result<ArrayList<SsSysBas>> getPaperTypes() {
        List<SsSysBas> list = examService.getPaperTypes();
        return ResultUtils.getSuccessResultList(list);
    }

    @ApiOperation(value = "题库地区列表", notes = "题库地区列表", produces = MediaType.APPLICATION_JSON_VALUE)
    @GetMapping("/paper/parameter/areas")
    public Result<ArrayList<SsSysBas>> getPaperAreas() {
        List<SsSysBas> list = examService.getPaperAreas();
        return ResultUtils.getSuccessResultList(list);
    }

    @ApiOperation(value = "题库年月列表", notes = "题库年月列表", produces = MediaType.APPLICATION_JSON_VALUE)
    @GetMapping("/paper/parameter/year-months")
    public Result<ArrayList<SsSysBas>> getPaperYearMonths() {
        List<SsSysBas> list = examService.getPaperYearMonths();
        return ResultUtils.getSuccessResultList(list);
    }

    @ApiOperation(value = "我的收藏列表", notes = "我的收藏列表", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @GetMapping("/collections")
    public Result<ArrayList<QuestionCollectionListOutVO>> getCollections(
            @Valid @ModelAttribute QuestionErrorCollectionListInVO questionErrorCollectionListInVO) {
        String userId = UserUtils.getUserId();
        questionErrorCollectionListInVO.setUserId(userId);
        String lastBelongYearMonth = executeBelongYearMonthURLDecoder(questionErrorCollectionListInVO.getLastBelongYearMonth());
        questionErrorCollectionListInVO.setLastBelongYearMonth(lastBelongYearMonth);
        List<QuestionCollectionListOutVO> questionCollectionListOutVOS = examService.getCollections(questionErrorCollectionListInVO);
        return ResultUtils.getSuccessResultList(questionCollectionListOutVOS);
    }

    @ApiOperation(value = "获取收藏内容列表", notes = "获取收藏内容列表", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @GetMapping("/collection/{belongYearMonth}/questions")
    public Result<QuestionCollectionVO> getCollectionQuestions(
            @ApiParam(value = "所属年月", required = true)
            @PathVariable("belongYearMonth") String belongYearMonth) {
        String userId = UserUtils.getUserId();
        belongYearMonth = executeBelongYearMonthURLDecoder(belongYearMonth);
        QuestionCollectionVO questionErrorVO = examService.getCollectionQuestions(userId, belongYearMonth);
        return ResultUtils.getSuccessResults(questionErrorVO);
    }

    @ApiOperation(value = "移除收藏", notes = "移除收藏", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @DeleteMapping("/collection/questions/{questionId}")
    public Result<String> deleteCollectionQuestion(
            @ApiParam(value = "收藏表Id", required = true) @PathVariable("questionId") Long questionId) {
        String userId = UserUtils.getUserId();
        examService.deleteCollectionQuestion(userId, questionId);
        return ResultUtils.getSuccessResults();
    }

    @ApiOperation(value = "清空收藏", notes = "清空收藏", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @DeleteMapping("/collection/questions")
    public Result<String> deleteCollectionQuestions() {
        String userId = UserUtils.getUserId();
        examService.deleteCollectionQuestions(userId);
        return ResultUtils.getSuccessResults();
    }

    @ApiOperation(value = "添加题目收藏", notes = "添加题目收藏", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @PostMapping("/collection/questions")
    public Result<String> postCollectionQuestions(@RequestBody CollectionQuestionVO collectionQuestionVO) {
        String userId = UserUtils.getUserId();
        examService.postCollectionQuestions(userId, collectionQuestionVO);
        return ResultUtils.getSuccessResults();
    }

    @ApiOperation(value = "热门题库列表", notes = "热门题库列表", produces = MediaType.APPLICATION_JSON_VALUE)
    @GetMapping("/paper/type-hots")
    public Result<ArrayList<PaperTypeHotVO>> getPaperTypeHots() {
        List<PaperTypeHotVO> paperTypeHots = examService.getPaperTypeHots();
        return ResultUtils.getSuccessResultList(paperTypeHots);
    }


    @ApiOperation(value = "文章测评作答", notes = "文章测评作答", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @PostMapping("/article/{articleId}/records")
    public Result<ArticleTestRecordOutVO> postArticleRecords(
            @ApiParam(value = "文章id", required = true) @PathVariable("articleId") Long articleId) {
        String userId = UserUtils.getUserId();
        ArticleTestRecordOutVO articleRecords = examService.postArticleRecords(userId, articleId);
        return ResultUtils.getSuccessResults(articleRecords);
    }

    @ApiOperation(value = "同步文章测评进度", notes = "同步文章测评进度", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @PutMapping("/article/records/{recordId}")
    public Result<String> putArticleRecords(
            @ApiParam(value = "文章测评记录id", required = true) @PathVariable("recordId") Long recordId,
            @Valid @RequestBody ArticleRecordInVO articleRecordInVO) {
        examService.putArticleRecords(recordId, articleRecordInVO);
        return ResultUtils.getSuccessResults();
    }

    @ApiOperation(value = "文章测评交卷", notes = "文章测评交卷", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @PostMapping("/article/records/{recordId}")
    public Result<String> postArticleRecordsById(
            @ApiParam(value = "记录id", required = true) @PathVariable("recordId") Long recordId,
            @Valid @RequestBody ArticleRecordInVO articleRecordInVO) {
        examService.postArticleRecordsById(recordId, articleRecordInVO);
        return ResultUtils.getSuccessResults();
    }

    @ApiOperation(value = "获取文章测评作答报告", notes = "获取文章测评作答报告", produces = MediaType.APPLICATION_JSON_VALUE)
    @LoginRequired
    @GetMapping("/article/records/{recordId}")
    public Result<ArticleTestRecordOutVO> getArticleRecords(
            @ApiParam(value = "文章测评记录Id", required = true) @PathVariable("recordId") Long recordId) {
        ArticleTestRecordOutVO articleTestRecordOutVO = examService.getArticleRecords(recordId);
        return ResultUtils.getSuccessResults(articleTestRecordOutVO);
    }

    /**
     * 所属年月 URL解码处理
     *
     * @param belongYearMonth
     */
    private String executeBelongYearMonthURLDecoder(String belongYearMonth) {
        if (StringUtils.isBlank(belongYearMonth)) {
            return null;
        }
        boolean isTrue = belongYearMonth.indexOf("%") != -1;
        if (isTrue) {
            try {
                belongYearMonth = URLDecoder.decode(belongYearMonth, "utf-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException("url解码失败", e);
            }
        }
        return belongYearMonth;
    }

}
